package com.fastCms.business.frame.aspects;

import com.alibaba.fastjson.JSON;
import com.fastCms.business.frame.constant.ResultCodeConst;
import com.fastCms.business.frame.exception.BusinessException;
import com.fastCms.business.frame.response.ApiResponse;
import com.fastCms.business.frame.response.ResponseUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.sql.SQLException;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @Description
 * @Param GlobalExceptionHandler
 * @Return
 * @Date 2019/3/7 下午4:35 lsquan
 */
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {

    /**
     * Business exception handler json object.
     *
     * @param exception the exception
     * @return the json object
     */
    @ExceptionHandler(value = BusinessException.class)
    public ApiResponse BusinessExceptionHandler(BusinessException exception) {
        log.error("---error----errorCode:" + exception.getCode() + "----errorMsg" + exception.toString());
        return ResponseUtil.fail(exception.getCode(), exception.getMessage());
    }

    @ExceptionHandler(value = RuntimeException.class)
    public ApiResponse RuntimeExceptionHandler(RuntimeException exception) {
        log.error(exception.getMessage(), exception);
        if (exception.getCause() instanceof SQLException) {//判断是否是sql异常
            return ResponseUtil.fail(ResultCodeConst.SQL_ERROR, ResultCodeConst.SQL_ERROR_MSG);
        }
        return ResponseUtil.fail(ResultCodeConst.SQL_ERROR, exception.getMessage());
    }


    /**
     * Business exception handler result message.
     * 校验异常捕获,统一返回
     *
     * @param exception the exception
     * @return the result message
     */
    @ExceptionHandler(value = ConstraintViolationException.class)
    public ApiResponse BusinessExceptionHandler(ConstraintViolationException exception) {
        Set<ConstraintViolation<?>> constraintViolations = exception.getConstraintViolations();
        String messages = constraintViolations.stream().map(constraintViolation -> constraintViolation.getMessage()).reduce((s, s2) -> s + "," + s2).get();
        log.error(exception.getMessage(), exception);
        return ResponseUtil.fail(ResultCodeConst.DATA_ERROR, messages);
    }

    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public ApiResponse MethodArgumentNotValidException(MethodArgumentNotValidException e) {
        log.error(e.getMessage(), e);
        List<ObjectError> errors = e.getBindingResult().getAllErrors();
        List<String> messages = errors.stream().map(error -> error.getDefaultMessage()).collect(Collectors.toList());
        return ResponseUtil.fail(ResultCodeConst.PARAM_ERROR, JSON.toJSONString(messages));
    }

    @ExceptionHandler(value = Exception.class)
    public ApiResponse OtherExceptionHandler(Exception e) {
        log.error(e.getMessage(), e);
        return ResponseUtil.fail(ResultCodeConst.FAIL_CODE, ResultCodeConst.FAIL_MSG);
    }

}
